#pragma once
#include <memory>

#include "../ast/SQLExpr.h"
#include "../ast/SQLName.h"
#include "../ast/SQLObject.h"
#include "../ast/SQLStatement.h"
#include "../ast/expr/SQLIdentifierExpr.h"
#include "../ast/expr/SQLListExpr.h"
#include "../ast/expr/SQLQueryExpr.h"
#include "../ast/expr/SQLVariantRefExpr.h"
#include "../../utils/common_ptr.h"
// #include "../ast/statement/SQLAlterTableAddColumn.h"
// #include "../ast/statement/SQLAlterTableAddConstraint.h"
// #include "../ast/statement/SQLAlterTableAddIndex.h"
// #include "../ast/statement/SQLAlterTableAlterColumn.h"
// #include "../ast/statement/SQLAlterTableDisableConstraint.h"
// #include "../ast/statement/SQLAlterTableDisableKeys.h"
// #include "../ast/statement/SQLAlterTableDropColumnItem.h"
// #include "../ast/statement/SQLAlterTableDropConstraint.h"
// #include "../ast/statement/SQLAlterTableEnableConstraint.h"
// #include "../ast/statement/SQLAlterTableEnableKeys.h"
// #include "../ast/statement/SQLAlterTableStatement.h"
#include "../ast/statement/SQLAssignItem.h"
// #include "../ast/statement/SQLCallStatement.h"
#include "../ast/statement/SQLColumnDefinition.h"
// #include "../ast/statement/SQLCommentStatement.h"
#include "../ast/statement/SQLConstraint.h"
// #include "../ast/statement/SQLCreateDatabaseStatement.h"
// #include "../ast/statement/SQLCreateIndexStatement.h"
// #include "../ast/statement/SQLCreateTableStatement.h"
// #include "../ast/statement/SQLCreateTriggerStatement.h"
// #include "../ast/statement/SQLCreateTriggerstatement/TriggerEvent.h"
// #include "../ast/statement/SQLCreateTriggerstatement/TriggerType.h"
// #include "../ast/statement/SQLCreateViewStatement.h"
// #include "../ast/statement/SQLDeleteStatement.h"
// #include "../ast/statement/SQLDropDatabaseStatement.h"
// #include "../ast/statement/SQLDropFunctionStatement.h"
// #include "../ast/statement/SQLDropIndexStatement.h"
// #include "../ast/statement/SQLDropProcedureStatement.h"
// #include "../ast/statement/SQLDropSequenceStatement.h"
// #include "../ast/statement/SQLDropTableSpaceStatement.h"
// #include "../ast/statement/SQLDropTableStatement.h"
// #include "../ast/statement/SQLDropTriggerStatement.h"
// #include "../ast/statement/SQLDropViewStatement.h"
#include "../ast/statement/SQLExprTableSource.h"
// #include "../ast/statement/SQLGrantStatement.h"
// #include "../ast/statement/SQLGrantstatement/ObjectType.h"
#include "../ast/statement/SQLInsertInto.h"
// #include "../ast/statement/SQLValuesClause.h"
// #include "../ast/statement/SQLInsertStatement.h"
#include "../ast/statement/SQLPrimaryKey.h"
// #include "../ast/statement/SQLReleaseSavePointStatement.h"
// #include "../ast/statement/SQLRollbackStatement.h"
// #include "../ast/statement/SQLSavePointStatement.h"
#include "../ast/statement/SQLSelect.h"
#include "../ast/statement/SQLSelectOrderByItem.h"
// #include "../ast/statement/SQLSelectStatement.h"
// #include "../ast/statement/SQLSetStatement.h"
#include "../ast/statement/SQLTableSource.h"
// #include "../ast/statement/SQLTruncateStatement.h"
// #include "../ast/statement/SQLUpdateSetItem.h"
// #include "../ast/statement/SQLUseStatement.h"
#include "../ast/statement/SQLWithSubqueryClause.h"

#include "SQLParser.h"

#include "../../DbType.h"
#include "../dialect/mysql/ast/FullTextType.h"
#include "../../utils/common_ptr.h"

class SQLExprParser;
class SQLCreateTableParser;
class SQLSelectParser;
class SQLUpdateStatement;
class SQLDropTableStatement;
class SQLDropUserStatement;
class SQLDropViewStatement;
class SQLDropTriggerStatement;
class SQLDropFunctionStatement;
class SQLDropTableSpaceStatement;
class SQLDropProcedureStatement;
class SQLDropStatement;
class SQLDropSequenceStatement;
class SQLRevokeStatement;
class SQLPrivilegeItem;
class SQLSelectListCache;
class SQLUseStatement;
class SQLDeleteStatement;
class SQLExplainStatement;

class SQLStatementParser : public SQLParser
{
public:
  SchemaRepository_ptr repository;
  SQLStatement_list_ptr statementList;
  SQLStatement_list_ptr yaList;
  SQLExprParser_ptr exprParser;
  BOOL_ptr exprParserHere;
  SQLSelectListCache_ptr selectListCache;
  time_t now;
  time_t currentDate;
  InsertColumnsCache_ptr insertColumnsCache;
  BOOL_ptr parseCompleteValues;
  int parseValuesSize;

  SQLDropTableStatement_ptr parseDropTable(BOOL_ptr acceptDrop);
  // SQLDropSequenceStatement *parseDropSequece(BOOL_ptr acceptDrop);
  SQLDropTriggerStatement_ptr parseDropTrigger(BOOL_ptr acceptDrop);
  SQLDropViewStatement_ptr parseDropView(BOOL_ptr acceptDrop);
  // SQLDropDatabaseStatement *parseDropDatabase(BOOL_ptr acceptDrop);
  SQLDropFunctionStatement_ptr parseDropFunction(BOOL_ptr acceptDrop);
  SQLDropTableSpaceStatement_ptr parseDropTablespace(BOOL_ptr acceptDrop);
  SQLDropProcedureStatement_ptr parseDropProcedure(BOOL_ptr acceptDrop);
  void parseInsert0(SQLInsertInto_ptr insertStatement);
  void parseInsert0_hinits(SQLInsertInto_ptr insertStatement);
  void parseInsert0(SQLInsertInto_ptr insertStatement, BOOL_ptr acceptSubQuery);
  virtual void parseUpdateSet(SQLUpdateStatement_ptr update);
  virtual SQLUpdateStatement_ptr createUpdateStatement();
  SQLAlterTableAddColumn_ptr parseAlterTableAddColumn();
  // SQLAlterTableAddIndex *parseAlterTableAddIndex();
  SQLStatement_ptr parseCreateResourceGroup();
  SQLStatement_ptr parseCreateMaterializedView();
  SQLDropStatement_ptr parseDropDatabaseOrSchema(BOOL_ptr acceptDrop);
  SQLDropStatement_ptr parseDropSchema();
  SQLDropSequenceStatement_ptr parseDropSequence(BOOL_ptr acceptDrop);
  SQLStatement_ptr parseDropEvent();
  SQLStatement_ptr parseDropResource();
  SQLStatement_ptr parseDropLogFileGroup();
  SQLStatement_ptr parseDropServer();
  SQLStatement_ptr parseDropTableGroup();
  SQLStatement_ptr parseDropRole();
  SQLStatement_ptr parseDropOutline();
  SQLStatement_ptr parseDropCatalog();
  FullTextType_ptr parseFullTextType();
  SQLStatement_ptr parseDropMaterializedView();
  SQLStatement_ptr parseDropOfflineModel();
  void parsePrivileages(SQLPrivilegeItem_list_ptr privileges, SQLObject_ptr parent);
  SQLExpr_ptr parseUser();

public:
  typedef SQLParser super;
  SQLStatementParser();
  ~SQLStatementParser();
  SQLStatementParser(string_ptr sql);
  SQLStatementParser(string_ptr sql, DbType_ptr dbType);

  SQLStatementParser(SQLExprParser_ptr exprParser);

  SQLExprParser_ptr getExprParser();

  SQLStatement_list_ptr parseStatementList();

  void parseStatementList(SQLStatement_list_ptr statementList);

  void parseStatementList(SQLStatement_list_ptr statementList, int max);
  void parseStatementList(SQLStatement_list_ptr statementList, int max, SQLObject_ptr parent);

  virtual SQLStatement_ptr parseRollback();

  virtual SQLStatement_ptr parseCommit();

  virtual SQLStatement_ptr parseShow();

  SQLUseStatement_ptr parseUse();

  SQLGrantStatement_ptr parseGrant();

  SQLStatement_ptr parseSavePoint();

  SQLStatement_ptr parseReleaseSavePoint();

  virtual SQLStatement_ptr parseAlter();

  // virtual void parseAlterDrop(SQLAlterTableStatement *stmt);

  virtual SQLStatement_ptr parseRename();

  SQLStatement_ptr parseTruncate();

  virtual SQLStatement_ptr parseInsert();

  virtual BOOL_ptr parseStatementListDialect(SQLStatement_list_ptr statementList);

  SQLDropUserStatement_ptr parseDropUser();

  SQLStatement_ptr parseDropIndex();

  SQLCallStatement_ptr parseCall();

  virtual SQLStatement_ptr parseSet();

  void parseAssignItems(SQLAssignItem_list_ptr items, SQLObject_ptr parent);
  void parseAssignItems(SQLAssignItem_list_ptr items, SQLObject_ptr parent, BOOL_ptr variant);

  virtual SQLStatement_ptr parseCreate();

  SQLStatement_ptr parseCreateDbLink();

  SQLStatement_ptr parseCreateTrigger();

  virtual SQLStatement_ptr parseBlock();

  virtual SQLStatement_ptr parseCreateDatabase();

  SQLStatement_ptr parseCreateProcedure();

  SQLStatement_ptr parseCreateSequence(BOOL_ptr acceptCreate);

  virtual SQLStatement_ptr parseCreateIndex(BOOL_ptr acceptCreate);

  SQLCreateTableParser_ptr getSQLCreateTableParser();

  virtual SQLStatement_ptr parseSelect();

  SQLSelectParser_ptr createSQLSelectParser();
  SQLSelectParser_ptr createSQLSelectParser(SQLExprParser_ptr exprParser);
  virtual SQLUpdateStatement_ptr parseUpdateStatement();
  virtual SQLDeleteStatement_ptr parseDeleteStatement();

  // virtual SQLCreateTableStatement *parseCreateTable();

  // SQLCreateViewStatement *parseCreateView();

  SQLCommentStatement_ptr parseComment();

  SQLStatement_ptr parseWith();
  SQLStatement_ptr parseStatement();
  SQLWithSubqueryClause_ptr parseWithQuery();
  virtual SQLExplainStatement_ptr parseExplain();
  SQLStatement_ptr parseCreateExternalCatalog();
  SQLStatement_ptr parseCreateTableGroup();
  SQLStatement_ptr parseCreateRole();
  SQLStatement_ptr parseShowMaterializedView();
  void parseInsertColumns(SQLInsertInto_ptr insert);
  SQLStatement_ptr parseDrop();
  SQLRevokeStatement_ptr parseRevoke();
  SQLSelectListCache_ptr getSelectListCache();
  void setSelectListCache(SQLSelectListCache_ptr selectListCache);
  void parseValueClauseNative(
      SQLInsertStatement_ValuesClause_list_ptr valueClauseList,
      SQLColumnDefinition_list_ptr columnDefinitionList,
      int columnSize,
      SQLObject_ptr parent);
  void parseValueClause(
      SQLInsertStatement_ValuesClause_list_ptr valueClauseList,
      int columnSize,
      SQLObject_ptr parent);
  void parseValueClause(SQLInsertValueHandler_ptr valueHandler);
  void parseValueClause(
      SQLInsertStatement_ValuesClause_list_ptr valueClauseList,
      SQLColumnDefinition_list_ptr columnDefinitionList,
      int columnSize,
      SQLObject_ptr parent);
  SQLStatement_ptr parseMerge();
  void parseHints(SQLHint_list_ptr hints);
  SQLErrorLoggingClause_ptr parseErrorLoggingClause();
  SQLStatement_ptr parseRefresh();
  SQLFetchStatement_ptr parseFetch();
  SQLOpenStatement_ptr parseOpen();
  SQLStatement_ptr parseClose();
  SQLStatement_ptr parseAlterIndex();
  SQLAlterSequenceStatement_ptr parseAlterSequence();
  SQLAlterTableItem_ptr parseAlterTableRename();
  SQLPartitionRef_ptr parsePartitionRef();
};
// typedef std::shared_ptr<SQLStatementParser> SQLStatementParser_ptr;

// #endif
